package com.xiaomazi.edu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaomazi.common.utils.R;
import com.xiaomazi.edu.client.OrderClient;
import com.xiaomazi.edu.dto.CourseInfoDTO;
import com.xiaomazi.edu.dto.CourseQuery;
import com.xiaomazi.edu.dto.front.CourseFrontDTO;
import com.xiaomazi.edu.entity.CourseDescription;
import com.xiaomazi.edu.entity.Subject;
import com.xiaomazi.edu.entity.Teacher;
import com.xiaomazi.edu.entity.Video;
import com.xiaomazi.edu.service.ChapterService;
import com.xiaomazi.edu.service.CourseDescriptionService;
import com.xiaomazi.edu.service.CourseService;
import com.xiaomazi.edu.service.SubjectService;
import com.xiaomazi.edu.service.TeacherService;
import com.xiaomazi.edu.service.VideoService;
import com.xiaomazi.edu.vo.ChapterResult;
import com.xiaomazi.edu.vo.CourseInfoResult;
import com.xiaomazi.edu.vo.CoursePublishResult;
import com.xiaomazi.edu.vo.front.CourseInfoVo;
import com.xiaomazi.servicebase.entity.CourseInfoToOrder;
import com.xiaomazi.servicebase.exception.LLXYException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaomazi.edu.mapper.CourseMapper;
import com.xiaomazi.edu.entity.Course;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private CourseDescriptionService courseDescriptionService;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private VideoService videoService;

    @Autowired
    private ChapterService chapterService;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private OrderClient orderClient;

    /**
     * 添加课程
     * @return CourseResponse
     */
    @Override
    @Transactional
    public R addCourseInfo(CourseInfoDTO courseInfoDTO) {

        Course course = BeanUtil.copyProperties(courseInfoDTO, Course.class);
        boolean courseRows = this.save(course);
        if (!courseRows){
            throw new LLXYException(20001,"添加课程信息失败");
        }

        String courseId = course.getId();
        CourseDescription courseDescription = new CourseDescription();
        courseDescription.setDescription(courseInfoDTO.getDescription());
        courseDescription.setId(courseId);
        boolean courseDescRows = courseDescriptionService.save(courseDescription);
        if (!courseDescRows){
            throw new LLXYException(20001,"课程描述添加失败");
        }
        //返回添加之后课程id，为了后面添加大纲使用
        return R.ok().data("courseId",courseId);
    }

    /**
     * 根据课程Id查询课程信息
     * @param courseId 课程id
     * @return CourseResult
     */
    @Override
    public R courseInfo(String courseId) {
        Course course = this.getById(courseId);
        CourseDescription courseDescription = courseDescriptionService.getById(courseId);

        CourseInfoResult courseInfoResult = BeanUtil.copyProperties(course, CourseInfoResult.class);
        courseInfoResult.setDescription(courseDescription.getDescription());
        return R.ok().data("courseInfoResult",courseInfoResult);
    }

    /**
     * 根据课程Id修改课程信息
     * @param courseInfoDTO
     * @return
     */
    @Override
    @Transactional
    public R uploadCourseInfo(CourseInfoDTO courseInfoDTO) {
        //1 修改课程表
        Course course = BeanUtil.copyProperties(courseInfoDTO, Course.class);
        this.updateById(course);
        //2 修改描述表
        CourseDescription courseDescription = BeanUtil.copyProperties(courseInfoDTO, CourseDescription.class);
        courseDescriptionService.updateById(courseDescription);
        return R.ok().data("courseId",courseInfoDTO.getId());
    }

    /**
     * 根据课程id查询课程信息
     * @param id 课程id
     * @return courseVo
     */
    @Override
    public R publishCourseInfo(String id) {
        CoursePublishResult coursePublishResult = courseMapper.publishCourseInfo(id);
        return R.ok().data("publishCourse",coursePublishResult);
    }

    /**
     * 根据课程Id修改课程状态为已发布状态
     * @param id 课程id
     * @return ok
     */
    @Override
    public R updateStatusById(String id) {
        return this.update().set("status","Normal").update() ? R.ok() : R.error();
    }

    /**
     * 根据课程id删除课程 包括课程章节和小节和视频
     * @param id 课程id
     * @return ok
     */
    @Override
    @Transactional
    public R removeCourseById(String id) {
        videoService.deleteVideoByCourseId(id);
        chapterService.deleteChapterByCourseId(id);
        courseDescriptionService.removeById(id);
        boolean isSuccess = this.removeById(id);
        return isSuccess?R.ok():R.error();
    }

    /**
     * 根据课程条件分页查询课程
     * @param courseFrontDTO 课程条件
     * @return 课程数据
     */
    @Override
    public R getCourseList(CourseFrontDTO courseFrontDTO) {
        //2 根据讲师id查询所讲课程
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        //判断条件值是否为空，不为空拼接
        if(StrUtil.isNotBlank(courseFrontDTO.getSubjectParentId())) { //一级分类
            wrapper.eq("subject_parent_id",courseFrontDTO.getSubjectParentId());
        }
        if(StrUtil.isNotBlank(courseFrontDTO.getSubjectId())) { //二级分类
            wrapper.eq("subject_id",courseFrontDTO.getSubjectId());
        }
        if(StrUtil.isNotBlank(courseFrontDTO.getBuyCountSort())) { //关注度
            wrapper.orderByDesc("buy_count");
        }
        if (StrUtil.isNotBlank(courseFrontDTO.getGmtCreateSort())) { //最新
            wrapper.orderByDesc("gmt_create");
        }
        if (StrUtil.isNotBlank(courseFrontDTO.getPriceSort())) {//价格
            wrapper.orderByDesc("price");
        }

        IPage<Course> page = new Page<>(courseFrontDTO.getCurrent(),courseFrontDTO.getSize());
        page = this.page(page,wrapper);
        return R.ok().data("courseList",page.getRecords()).data("total",page.getTotal());
    }

    /**
     * 根据课程id查询课程信息
     * @param courseId 课程id
     * @return 课程数据 CourseInfoVo
     */
    @Override
    public R getCourseByCourseId(String courseId,String userId) {
        CourseInfoVo courseInfoVo = baseMapper.getBaseCourseInfo(courseId);
        List<ChapterResult> chapterResult = chapterService.getChapterInfoByCourseId(courseId);
        boolean isbuy = orderClient.isBuyCourse(courseId, userId);
        return R.ok().data("courseInfo",courseInfoVo).data("chapterResult",chapterResult)
                .data("isbuy",isbuy);
    }

    /**
     * 根据课程ID查询出课程信息 供生成订单调用
     * @param courseId 课程id
     * @return CourseInfoToOrder
     */
    @Override
    public CourseInfoToOrder getCourseToOrderByCourseId(String courseId) {
        Course course = this.getById(courseId);
        if (null == course){
           throw new LLXYException(20001,"课程不存在");
        }
        CourseInfoToOrder courseInfoToOrder = BeanUtil.copyProperties(course, CourseInfoToOrder.class);
        Teacher teacher = teacherService.getById(course.getTeacherId());
        courseInfoToOrder.setTeacherName(teacher.getName());
        courseInfoToOrder.setTotalFee(course.getPrice());
        return courseInfoToOrder;
    }

    /**
     * 根据课程条件筛选出课程并分页
     * @param courseQuery 课程条件
     * @return course
     */
    @Override
    public R pageCourseCondition(CourseQuery courseQuery) {
        String title = courseQuery.getTitle();
        String status = courseQuery.getStatus();
        String begin = courseQuery.getBegin();
        String end = courseQuery.getEnd();
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();

        if (StrUtil.isNotBlank(title)){
            queryWrapper.eq("title",title);
        }

        if (StrUtil.isNotBlank(status)){
            queryWrapper.eq("status",status);
        }
        if (StrUtil.isNotBlank(begin)){
            queryWrapper.ge("gmt_create",begin);
        }
        if (StrUtil.isNotBlank(end)){
            queryWrapper.le("gmt_create",end);
        }

        queryWrapper.orderByDesc("gmt_create");

        IPage<Course> coursePage = new Page<>(courseQuery.getCurrent(),courseQuery.getSize());
        coursePage = this.page(coursePage,queryWrapper);
        return R.ok().data("total",coursePage.getTotal()).data("rows",coursePage.getRecords());
    }
}
